package concordia.comp6231.frontend;

import java.net.InetAddress;

import org.omg.CORBA.ORB;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;

import concordia.comp6231.boxOfficeService.MyService;
import concordia.comp6231.boxOfficeService.MyServiceHelper;
import concordia.comp6231.boxOfficeService.MyServicePOA;

public class BoxOfficeFrontEndImpl extends MyServicePOA {
	
	public static String LEADER_REPLICA_SERVICE_NAME = "LEADER_REPLICA_SERVICE"; 
	
	private static MyService serviceImpl;
	private final int BOX_OFFICE_ID_LENGTH = 3;
	private String boxOfficeID;
	private ORB orb;

	public void setORB(ORB orb_val) {
		orb = orb_val;
	}	

	public BoxOfficeFrontEndImpl() {
	}
	
	public void setBoxOfficeID(String boxOfficeID) {
		if (boxOfficeID == null || boxOfficeID.length() != BOX_OFFICE_ID_LENGTH) {
			throw new IllegalArgumentException("Invalid boxOfficeID value, boxOfficeID should be a String of length " + BOX_OFFICE_ID_LENGTH);
		}
		this.boxOfficeID = boxOfficeID;
	}
	
	public String getBoxOfficeID() {
		return boxOfficeID;
	}
	
	@Override
	public int check(String showID) {
		try {
			System.out.println("Check action receievd for showID: " + showID);
			// get the root naming context
			// LEADER_REPLICA_SERVICE_NAME
			org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
			// Use NamingContextExt instead of NamingContext, part of the Interoperable naming Service.
			NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
			// resolve the Object Reference in Naming
			String objName = boxOfficeID;
			serviceImpl = MyServiceHelper.narrow(ncRef.resolve_str(LEADER_REPLICA_SERVICE_NAME + "_" + objName));
			System.out.println("Obtained a handle on server object: " + serviceImpl);
			int availableTickets = serviceImpl.check(showID);
			System.out.println("Received availableTickets: " + availableTickets);
			return availableTickets;
		} catch (Exception e) {
			System.err.println(e.getMessage());
			//@todo: throw Remote Exception
		}
		// dummy return, should be removed later
		return -1;
	}
	
	@Override
	public void reserve(String customerID, String showID, int numberOfTickets) {
		try {
			System.out.println("Reserve action receievd: customerID=" + customerID + ", showID=" + showID + ", numberOfTickets=" + numberOfTickets);
			// get the root naming context
			org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
			// Use NamingContextExt instead of NamingContext, part of the Interoperable naming Service.
			NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
			// resolve the Object Reference in Naming
			String objName = boxOfficeID;
			serviceImpl = MyServiceHelper.narrow(ncRef.resolve_str(LEADER_REPLICA_SERVICE_NAME + "_" + objName));
			System.out.println("Obtained a handle on server object: " + serviceImpl);
			serviceImpl.reserve(customerID, showID, numberOfTickets);
		} catch (Exception e) {
			System.err.println(e.getMessage());
			//@todo: throw Remote Exception
		}
	}

	@Override
	public void cancel(String customerID, String showID, int numberOfTickets) {
		try {
			System.out.println("Cancel action receievd: customerID=" + customerID + ", showID=" + showID + ", numberOfTickets=" + numberOfTickets);
			// get the root naming context
			org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
			// Use NamingContextExt instead of NamingContext, part of the Interoperable naming Service.
			NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
			// resolve the Object Reference in Naming
			String objName = boxOfficeID;
			serviceImpl = MyServiceHelper.narrow(ncRef.resolve_str(LEADER_REPLICA_SERVICE_NAME + "_" + objName));
			System.out.println("Obtained a handle on server object: " + serviceImpl);
			serviceImpl.cancel(customerID, showID, numberOfTickets);
		} catch (Exception e) {
			System.err.println(e.getMessage());
			//@todo: throw Remote Exception
		}
	}

	@Override
	public void exchange(String customerID, String reservedShowID, int reservedTickets, String desiredShowID, int desiredTickets) {
		try {
			System.out.println("Exchange action receievd");
			// get the root naming context
			org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
			// Use NamingContextExt instead of NamingContext, part of the Interoperable naming Service.
			NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
			// resolve the Object Reference in Naming
			String objName = boxOfficeID;
			serviceImpl = MyServiceHelper.narrow(ncRef.resolve_str(LEADER_REPLICA_SERVICE_NAME + "_" + objName));
			System.out.println("Obtained a handle on server object: " + serviceImpl);
			serviceImpl.exchange(customerID, reservedShowID, reservedTickets, desiredShowID, desiredTickets);
		} catch (Exception e) {
			System.err.println(e.getMessage());
			//@todo: throw Remote Exception
		}
	}

	@Override
	public String getHostname() {
		String computerName = "";
		try {
		    computerName = InetAddress.getLocalHost().getHostName();
		} catch(Exception e) {
			throw new IllegalStateException(e.getMessage());
		}
		return computerName;
	}
	
}
